package co.edu.aes.patrones.cliente.receptor;

import co.edu.aes.patrones.cliente.ventanas.Cliente;
import co.edu.aes.patrones.forwardreceiver.mensajes.MensajeTCP;
import co.edu.aes.patrones.forwardreceiver.receptor.ReceptorTCP;
import co.edu.aes.patrones.forwardreceiver.utilidades.ComunicacionException;
import co.edu.aes.patrones.forwardreceiver.utilidades.TipoComunicacion;
import co.edu.aes.patrones.forwardreceiver.utilidades.Utilidades;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Hilo Receptor del Despachador el cual tiene la función de estar pendiente de mensajes entrantes y realizar
 *  alguna acción correspondiente.
 * @author Alejandro León
 * @author Alejandro Peña
 * @author Diego Escobar.
 */
public class Receptor extends Thread {

    private static final int MAXIMO_DE_CONEXIONES = 10;
    /**
     * Punto de comunicación entrante TCP.
     */
    private ServerSocket socketServidorTCP;
    /**
     * Conexión entrante.
     */
    private Socket socketClienteTCP;
    
    private Cliente cliente;

    /**
     * Inicio de configuración del Receptor según el tipo de comunicación a utilizar.
     * @param cliente 
     * @param puerto Puerto donde se encontrará el receptor escuchando.
     * @param tipoComunicacion El tipo de comunicación a configurar TCP.
     * @throws ComunicacionException
     */
    public Receptor(Cliente cliente,int puerto, TipoComunicacion tipoComunicacion) throws ComunicacionException {
        
            this.cliente = cliente;
            String direccionIP = Utilidades.resolverDireccionLocal();            
            if (direccionIP == null) {
                throw new ComunicacionException("La configuración del receptor no se pudo realizar");
            }

            InetAddress direccionLocal;
            try {
                direccionLocal = InetAddress.getByName(direccionIP);
                socketServidorTCP = new ServerSocket(puerto, MAXIMO_DE_CONEXIONES, direccionLocal);
            } catch (UnknownHostException ex) {
                throw new ComunicacionException("La configuración del receptor no se pudo realizar. No se cuenta con una dirección IP local válida", ex);
            } catch (IOException ex) {
                throw new ComunicacionException("La configuración del receptor no se pudo realizar", ex);
            }
        
    }
    /**
     * Método encargado de iniciar un hilo receptor de mensajes según la configuración inicial de comunicación.
     * Escucha mensajes de actualización de la frecuencia de toma de temperatura.
     */
    @Override
    public synchronized void run() {
        while (true) {
            try {
                socketClienteTCP = socketServidorTCP.accept();
                ReceptorTCP receptorTCP = new ReceptorTCP(socketClienteTCP);
                MensajeTCP recibido = receptorTCP.recibir();
                cliente.setFrecuencia(Long.parseLong(recibido.getFrecuenciaLectura()));
                Logger.getLogger(Receptor.class.getName()).log(Level.INFO, "Se actualiza temperatura a {0}\u00b0C por notificación de: {1}", new Object[]{ recibido.getFrecuenciaLectura(), recibido.getNombreDireccion()});
                //logica entrada cambiar temperatura.
            } catch (IOException ex) {
                Logger.getLogger(Receptor.class.getName()).log(Level.SEVERE, "No se pudo llevar a cabo la conexión entrante", ex);
            } catch (ComunicacionException ex) {
                Logger.getLogger(Receptor.class.getName()).log(Level.SEVERE, "No se pudo llevar a cabo la conexión entrante", ex);
            }
        }
    }
}
